/* eslint-disable no-dupe-class-members */
/* eslint-disable @typescript-eslint/no-unsafe-call */
import { render, createVNode } from 'vue';

import { ElLoading } from 'element-plus';
import { ElMessage as elMessage, ElMessageBox } from 'element-plus';
import type { Action } from 'element-plus';
// / <reference path="timers.d.ts" />

import MyConfirmVue from './MyConfirm.vue';

const divConfirm = document.createElement('div');
divConfirm.setAttribute('class', 'xc-confirm');
document.body.appendChild(divConfirm);

interface Loading {
    close: () => void;
}

interface ILoadingParam {
    target?: HTMLElement;
    fullscreen?: boolean;
    text?: string;
    spinner?: string;
    background?: string;
}

/* 对 element 消息弹窗 进行封装 方便统一修改*/
export default class XCMessageMgr {
    private static _instance: XCMessageMgr | null = null;
    static get Instance() {
        if (XCMessageMgr._instance === null) {
            XCMessageMgr._instance = new XCMessageMgr();
        }
        return XCMessageMgr._instance;
    }

    private constructor() {
        XCMessageMgr._instance = null;
    }

    // loading相关
    private loadingInstance: Loading | null = null;

    private timer: any = null;
    showLoading(option?: ILoadingParam) {
        this.loadingInstance = ElLoading.service({
            fullscreen: option?.fullscreen,
            text: option?.text,
            spinner: option?.spinner,
            background: option?.background,
        });
        if (this.timer) {
            // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
            clearTimeout(this.timer);
        }
        this.timer = setTimeout(() => {
            this.hideLoading();
            this.timer = null;
        }, 10000);
    }
    hideLoading() {
        if (this.loadingInstance) {
            this.loadingInstance.close();
        }
    }

    // 二次确认框相关
    showConfirm(text: string, cb: (r: boolean) => void): void;
    showConfirm(text: string): Promise<object>;
    showConfirm(text: string, cb?: (r: boolean) => void): Promise<object> | void {
        // 渲染自己的结构
        // if(text && cb) {
        //     render(null, divConfirm);
        //     const confirmVnode = createVNode(MyConfirmVue,{text,onok: cb});
        //     render(confirmVnode , divConfirm);
        //     return;
        // }

        const promise = new Promise<object>((resove, reject) => {
            ElMessageBox.confirm(text,'提示',{
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            })
                .then(() => {
                    cb ? cb(true) : resove({ data: true });
                })
                .catch(() => {
                    cb ? cb(false) : reject({ data: false });
                });
        });
        if (!cb) {
            return promise;
        }
    }

    private showMessage(text: string, type: 'success' | 'error' | 'warning') {
        elMessage[type](text);
    }
    showMessageError(text: string) {
        this.showMessage(text, 'error');
    }
    showMessageWarning(text: string) {
        this.showMessage(text, 'warning');
    }
    showMessageSuc(text: string) {
        this.showMessage(text, 'success');
    }

    // messagebox 消息弹出框相关
    showMessageBox(text: string): Promise<Action>;
    showMessageBox(text: string, cb: (r: Action | Error) => void): void;
    showMessageBox(text: string, cb?: (r: Action | Error) => void): Promise<Action> | void {
        const promise = new Promise<Action>((resove, reject) => {
            ElMessageBox.alert(text, {
                // if you want to disable its autofocus
                // autofocus: false,
                confirmButtonText: 'ok',
                callback: (action: Action) => {
                    elMessage({
                        type: 'info',
                        message: `action: ${action}`,
                    });
                    cb ? cb(action) : resove(action);
                },
            }).catch((data: Error) => {
                if (cb) {
                    cb(data);
                }
                cb ? cb(data) : reject(data);
            });
        });
        if (!cb) {
            return promise;
        }
    }
}
